package Checkers;

import java.util.Comparator;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.ListIterator;

public class StateNode implements Comparable {
	
	public StateNode(Board board, Move move, double value) {
		this.board = board;
		this.value = value;
		this.move = move;
		this.children = null;
		
		if (move == null)			// otherwise we'd never stop
			generateChildren(0);
	}
	
	public void generateChildren(int depth) {
		if (children != null)
			return;
		
		LinkedList<Move> moves = ValidMoves.getMoves(board);
		if (moves.size() == 0)
			return;
		
        ListIterator<Move> li = moves.listIterator();
        children = new StateNode[moves.size()];
        int i = 0;
        while( li.hasNext() ) {	            
            Move childMove = li.next();
            Board childBoard = (Board)board.clone();
            /* determination of value for child node
             * TODO : check for double jumps somehow, and concatenate to the childMove
             */
            double childValue;
            if (depth == 0)
            	childValue = childBoard.makeMove(childMove);
            else
            	childValue = childBoard.makeMove(childMove) * (1.0 / depth);	// the further away the move, the less weight it gains
            children[i] = new StateNode(childBoard, childMove, childValue);
            //System.out.println("generate: "+childMove+", with value: "+childValue);
            i++;
        }
        Arrays.sort(children);
	}
	
	
	public Board getBoard() {
		return board;
	}
	
	public StateNode[] getChildren() {
		return children;
	}
	
	public double getValue() {
		return value;
	}
	
	public int getNumChildren() {
		if (children == null)
			return 0;
		return children.length;
	}
	
	public Move getMove() {
		return move;
	}
	
	public void setValue(double value) {
		this.value = value;
	}	
	
	/**
	 * hacked up compareTo
	 */
	public int compareTo(Object o) {
		if (value < ((StateNode)o).getValue())
			return -1;
		if (value > ((StateNode)o).getValue())
			return 1;
		return 0;
	}
	
	private Board board;
	private double value;
	private Move move;
	private StateNode[] children;
}